package sagroup.dracots;

import lime2.Reaction;

public class DracoReaction {
	/**
	 * The reaction is fired once and then it is removed automatically from the
	 * reactive program.
	 */
	public static final byte ONCE = 1;

	/**
	 * The reaction is fired, and will never fire again for that given tuple,
	 * but remains registered. So, if multiple tuples enable the reaction, the
	 * reaction is fired for each of them.
	 */
	public static final byte ONCEPERTUPLE = 2;
	
	public static final byte ONCEPERTUPLEID = 3; //Version ID?

	// is it a once or once-per-tuple reaction ?
	// private byte mode;
	private Reaction innerReaction;
	
	private DracoReactionListener listener;
	
	private DracoTuple template;

	public DracoReaction(final byte mode, final DracoTuple template,
			final DracoReactionListener listener) {
		
		
		// parameter checking
		if (((mode != ONCE) && (mode != ONCEPERTUPLE) && (mode != ONCEPERTUPLEID))
				|| template == null || listener == null)
			throw new IllegalArgumentException("invalid/null value");

		else {
			this.listener = listener;
			this.template = template;

			switch (mode) {
			case ONCE:
				//fall through
			case ONCEPERTUPLE:
				innerReaction = new Reaction(mode, template.toLimeTemplate(),
						listener.innerListener);
				break;
			case ONCEPERTUPLEID:
				throw new RuntimeException("Not Implemented");
			default:
				break;
			}
		}
	}
	
	public DracoReactionListener getListener() {
		return listener;
	}
	
	public DracoTuple getTemplate() {
		return template;
	}

	/**
	 * Convert a DracoReaction array to a Reaction array
	 * @param reactions
	 * @return
	 * @author Xing Jiankuan
	 */
	public static Reaction[] getLimeReactions(DracoReaction[] reactions) {
		Reaction toReturn[] = new Reaction[reactions.length];
		for (int i = 0; i < reactions.length; i++) {
			toReturn[i] = reactions[i].innerReaction;
		}
		return toReturn;
	}

	public int getMode() {
		return innerReaction.getMode();
	}
}
